*******************************************************************************
******************* REPLICATION DO-FILE FOR THE PAPER: ************************
***** A CREDIBLE CHANGE: HOW PARTIES USE ELECTION PROMISES TO COUNTERACT ******
****** THE LOSS OF REPUTATION WHEN THEY DILUTE THEIR POLICY POSITIONS *********
**************** (PUBLISHED IN POLITICAL COMMUNICATION) ***********************
*******************************************************************************
cd "C:\Users\replication" // Change this to the folder on your computer in which you have placed the replication files

**# Generate sub-folder
capture mkdir data 
capture mkdir output

**# PARTYFACTS_ID
copy "https://partyfacts.herokuapp.com/download/external-parties-csv/" "partyfacts-mapping.csv", replace
insheet using "partyfacts-mapping.csv", clear
keep if inlist(dataset_key, "parlgov", "manifesto")
destring dataset_party_id, replace
save "partyfacts.dta", replace

**# COMPARATIVE MANIFESTO PROJECT
*CMP categories
import excel using "cmp.xlsx", firstrow clear
save "cmp.dta", replace

*Importing dataset
use "MPDataset_MPDS2020b_stata14.dta", clear // Link to download: https://manifesto-project.wzb.eu/down/data/2020b/datasets/MPDataset_MPDS2020b_stata14.dta (For the link to work, it may require that you are logged in first.)

keep country countryname per* party partyname partyabbrev date total parfam rile
rename (pervote peruncod) (vote per999)
rename (country countryname party per*) (country_num country dataset_party_id share*)

reshape long share, i(dataset_party_id date) j(cmp_code) string

*Grouping cmp_code to positional issues
merge m:1 cmp_code using "cmp.dta", gen(_cmp) keep(master match)
           
*Adding partyfacts_id 
g dataset_key = "manifesto"
merge m:1 dataset_key dataset_party_id using "partyfacts.dta" , keep(master match) gen(_pfmanifesto) keepusing(partyfacts_id)

g pf_common_id = partyfacts_id
	replace pf_common_id = dataset_party_id if pf_common_id == .
	
*Number of sentences within each issue
g sentences_del = round(total/100*share)

*If more than one manifesto:
bys pf_common_id date cmp_code: egen sentences_new_del = total(sentences_del), missing // If there is more than one manifesto under the same pf_common_id (combining partyfacts id & manifesto id), I sum their sentences together
bys pf_common_id date cmp_code: egen rile_index = mean(rile) // If there is more than one manifesto under the same pf_common_id (combining partyfacts id & manifesto id), I take the mean RILE value

bys pf_common_id date cmp_code (partyname): gen n = _n
bys pf_common_id date cmp_code (partyname): egen max = max(n)
keep if n == 1 // If there is more than one manifesto, I only keep one of the observations (after combining information from all manifestoes, see above)

*Total number of sentences in a manifesto
bys pf_common_id date: egen sentences_total = total(sentences_new_del)

*Counting number of sentences within broad issue categories
bys country pf_common_id date issue ideo: egen sentences = total(sentences_new_del), missing
egen tag = tag(country pf_common_id date issue ideo)
keep if tag == 1

*Reshaping to issue level (left/right on the same row)
keep if inlist(ideo, "Left", "Right")
keep country sentences pf_common_id partyname parfam date issue sentences_total ideo n max rile_index
reshape wide sentences, i(pf_common_id  date issue) j(ideo) string

*Number of parties
bysort country date issue (pf_common_id): g partyissuenumber = _n
bysort country date issue: egen partyissuetotalnumber = max(partyissuenumber)

*Generating saliency variable 
g Saliency = log((sentencesLeft + sentencesRight + 1)/sentences_total)
bysort pf_common_id issue (date):  g LSaliency =  Saliency[_n-1]

*Generating position and position change variables
g Position =  log(sentencesRight + 0.5) - log(sentencesLeft + 0.5) // Position (using log-measure
	replace Position = . if sentencesRight == 0 & sentencesLeft == 0 // Issues that parties do not mention are missing

g PositionAbs = abs(Position)
bysort pf_common_id date: egen meanPositionAbs = mean(PositionAbs)

bysort pf_common_id issue (date):  g PositionChange = Position - Position[_n-1]
g PositionChangeAbs = abs(PositionChange)

bysort pf_common_id issue (date): g PositionChangeTypeDetail = 0 if Position == Position[_n-1] & Position!=. 
bysort pf_common_id issue (date): replace PositionChangeTypeDetail = 1 if !inlist(Position,0,.) & inlist(Position[_n-1], 0) & PositionChangeTypeDetail==. // Crystalization (from center to one of the two sides)
bysort pf_common_id issue (date): replace PositionChangeTypeDetail = 2 if (Position < Position[_n-1] & Position < 0 & Position[_n-1] < 0 | Position > Position[_n-1] & Position > 0 & Position[_n-1] > 0 & Position <.) & PositionChangeTypeDetail==. // Crystalization (becoming more extreme on one of the two sides)
bysort pf_common_id issue (date): replace PositionChangeTypeDetail = 3 if (Position > Position[_n-1] & Position <= 0 | Position < Position[_n-1] & Position >= 0 & Position<. & Position[_n-1] <.) & PositionChangeTypeDetail==. // Dilution (moving towards the center)
bysort pf_common_id issue (date): replace PositionChangeTypeDetail = 4 if (Position > 0 & Position <. & Position[_n-1] < 0  | Position < 0 & Position[_n-1] > 0 & Position[_n-1] <.) & PositionChangeTypeDetail==. // Dilution (crossing the center)

g PositionChangeType3 = .
	replace PositionChangeType3 = 0 if inlist(PositionChangeTypeDetail, 0) | PositionChangeAbs < 3.0
	replace PositionChangeType3 = 1 if inlist(PositionChangeTypeDetail, 1, 2) & PositionChangeAbs >= 3.0
	replace PositionChangeType3 = 2 if inlist(PositionChangeTypeDetail, 3, 4) & PositionChangeAbs >= 3.0
	
g PositionChangeType2 = .
	replace PositionChangeType2 = 0 if inlist(PositionChangeTypeDetail, 0) | PositionChangeAbs < 2.0
	replace PositionChangeType2 = 1 if inlist(PositionChangeTypeDetail, 1, 2) & PositionChangeAbs >= 2.0
	replace PositionChangeType2 = 2 if inlist(PositionChangeTypeDetail, 3, 4) & PositionChangeAbs >= 2.0

g PositionChangeType1 = .
	replace PositionChangeType1 = 0 if inlist(PositionChangeTypeDetail, 0) | PositionChangeAbs < 1.0
	replace PositionChangeType1 = 1 if inlist(PositionChangeTypeDetail, 1, 2) & PositionChangeAbs >= 1.0
	replace PositionChangeType1 = 2 if inlist(PositionChangeTypeDetail, 3, 4) & PositionChangeAbs >= 1.0

g PositionChangeType05 = .
	replace PositionChangeType05 = 0 if inlist(PositionChangeTypeDetail, 0) | PositionChangeAbs < 0.5
	replace PositionChangeType05 = 1 if inlist(PositionChangeTypeDetail, 1, 2) & PositionChangeAbs >= 0.5
	replace PositionChangeType05 = 2 if inlist(PositionChangeTypeDetail, 3, 4) & PositionChangeAbs >= 0.5

g PositionChangeType1Simple = 1 if PositionChangeType1 == 2 
	replace PositionChangeType1Simple = 0 if inlist(PositionChangeType1, 0, 1)

g PositionChangeCen = PositionChangeAbs if inlist(PositionChangeTypeDetail, 3, 4)
	replace PositionChangeCen = -PositionChangeAbs  if inlist(PositionChangeTypeDetail, 1, 2)
	replace PositionChangeCen = 0 if PositionChangeTypeDetail == 0

g PositionChangeCenZero = PositionChangeAbs if inlist(PositionChangeTypeDetail, 3, 4)
	replace PositionChangeCenZero = 0  if inlist(PositionChangeTypeDetail, 1, 2)
	replace PositionChangeCenZero = 0 if PositionChangeTypeDetail == 0

*RILE index
g rile_index_abs = abs(rile_index)

*Mainstream versus niche parties
g mainstream = 1 if inlist(parfam, 30, 40, 50, 60)
	replace mainstream = 0 if inlist(parfam, 10, 20, 70, 80, 90, 95)
	
save "manifesto.dta", replace

**# PARLGOV
**# - Vote information
copy "https://dataverse.harvard.edu/api/access/datafile/10437092" "view_election.tab", replace // Version: 2024-08-12)
import delimited "view_election.tab", clear encoding(UTF-8) bindquote(strict) 

g election_date_num = date(election_date, "YMD")
	rename (party_id vote_share) (dataset_party_id vote_share_delete)
	keep if election_type=="parliament"
	g dataset_key = "parlgov"
	merge m:1 dataset_key dataset_party_id using "partyfacts.dta", keep(master using match) gen(_pfparlgov) keepusing(partyfacts_id) // keep(match)

	g pf_common_id = partyfacts_id
	replace pf_common_id = dataset_party_id if pf_common_id == .

	bys pf_common_id election_date: egen vote_share = total(vote_share_delete) // If there is more than one party under the same pf_common_id (combining partyfacts id & parlgov id), I sum their vote share

	egen tag = tag(pf_common_id election_date_num)
	keep if tag == 1
	
save "view_election.dta", replace

**# - Main dataset
copy "https://dataverse.harvard.edu/api/access/datafile/10437088" "view_cabinet.tab", replace // Version: 2024-08-12)
import delimited "view_cabinet.tab", clear encoding(UTF-8) // 
	append using "us.dta" // Adding US data (president status) to parlgov dataset 
	rename (country_name party_id) (country dataset_party_id)
	
*Date variables
g election_date_num = date(election_date, "YMD")
g start_date_num = date(start_date, "YMD")
keep if election_date_num>0

save "view_cabinet.dta", replace 

**# - All parties in each country
use "view_cabinet.dta", replace 
egen party_each = tag(country dataset_party_id)
keep if party_each==1
keep country dataset_party_id
save "parties.dta", replace

**# - All elections in each country
use "view_cabinet.dta", replace 
egen election_each = tag(country election_date_num)
keep if election_each==1
keep country election_date_num

*Next election
bys country (election_date_num): g election_date_num_next = election_date_num[_n + 1]
g date_next = year(election_date_num_next) * 100 + month(election_date_num_next)

save "elections.dta", replace

**# - All governments in each country
use "view_cabinet.dta", replace 

egen government_each = tag(country election_date_num start_date_num)
keep if government_each==1
keep country election_date_num start_date_num

*Number of governments within election period
bys country election_date_num (start_date_num): g gov = _n

*Last government before election 
bys country election_date_num: egen gov_last = max(gov)

*Saving
save "governments.dta", replace


**# - Merging  parlgov-files
use "governments.dta", replace
merge m:1 country election_date_num using "elections.dta",  nogen
joinby country using "parties.dta"
merge 1:1 country election_date_num start_date dataset_party_id using "view_cabinet.dta", keepusing(cabinet_party election_date dataset_party_id party_name seats election_seats_total)

*Adding partyfacts_id 
g dataset_key = "parlgov"
merge m:1 dataset_key dataset_party_id using "partyfacts.dta", keep(master using match) gen(_pfparlgov) keepusing(partyfacts_id)
	replace partyfacts_id = 432 if dataset_party_id == 9998 // US: Democratic Party
	replace partyfacts_id = 809 if dataset_party_id == 9999 // US: Republican Party
		
g pf_common_id = partyfacts_id
	replace pf_common_id = dataset_party_id if pf_common_id == .

bys country election_date_num start_date pf_common_id (cabinet_party): g n = _n
keep if n == 1 

*Last government before the election
g gov_before_election = 1 if gov==gov_last
keep if gov_before_election == 1
	
*Parliament experience
bys country pf_common_id election_date_num: egen parl_present_times = total(cabinet_party==0 | cabinet_party==1) //The number of government periods in which a party has been present in parliament
g parl_present = 1 if parl_present_times>0 & parl_present_times<. // Whether or not a party has been present in parliament during an election period

egen tag = tag(country election_date_num parl_present pf_common_id)
bys country pf_common_id tag (election_date_num): g parl_experience_delete = _n if tag==1
bys country pf_common_id election_date_num: egen parl_experience = min(parl_experience_delete) // parl_experience = number of election periods a party has been represented (including the specific election_period)
bys country pf_common_id (election_date_num): replace parl_experience = parl_experience[_n-1] if parl_experience == .
	replace parl_experience = 0 if parl_experience == .
	
drop tag

*Vote share
merge m:1 election_date pf_common_id using "view_election.dta", keepusing(vote_share) keep(match master) gen(_view_election)
replace vote_share = 0 if cabinet_party==.

*Saving
save "parlgov.dta", replace


**# POLCOMMIT
copy "https://dataverse.harvard.edu/api/access/datafile/10951688" "polcommit_v2.0.csv", replace
import delimited "polcommit_v2.0.csv", clear encoding(UTF-8) // 

*Adding partyfacts_id 
rename (party countryname) (dataset_party_id country)
g dataset_key="manifesto"
merge m:1 dataset_key dataset_party_id using "partyfacts.dta", keep(master match) gen(_pfpolcommit) keepusing(partyfacts_id)

g pf_common_id = partyfacts_id
	replace pf_common_id = dataset_party_id if pf_common_id == .

*CMP-categories
replace cmp_code = subinstr(cmp_code, ".", "_", .) if cmp_code!="."
replace cmp_code = "000" if inlist(cmp_code, "NA", "0")

merge m:1 cmp_code using "cmp.dta", keepusing(cmprecode) keep(master match) gen(merge1) // Adding adjusted cmp categories to master dataset to correctly merge with issue categories in manifesto data
replace cmp_code = cmprecode // 
merge m:1 cmp_code using "cmp.dta", keepusing(issue ideo) keep(match master) gen(merge2)

* Each sentence gets the value 1
g one = 1

*Number of characters within a quasi-sentence 
gen text_ch = strlen(text)

*Total number of characters within within each issue
bys country pf_common_id date issue: egen i_commitment_characters = total(cond(commitment==1,text_ch,.))
bys country pf_common_id date issue: egen i_characters = total(text_ch)

*Total number of quasi-sentences within each issue
bys country pf_common_id date issue: egen i_sentences = total(one)

*Total number of commitments within each issue
bys country pf_common_id date issue: egen i_commitment = total(commitment==1)

*Share of commitments (character-weighted)
g sh_i_char_commitment = (i_commitment * i_commitment_characters)/(i_sentences*i_characters)*100

egen issue_level = tag(country pf_common_id date issue)
keep if issue_level==1
keep country pf_common_id date issue i_sentences i_commitment* sh_i_char_commitment

save "polcommit.dta", replace


**# MERGING THE DATASETS
use "manifesto.dta", clear

merge 1:1 country date pf_common_id issue using "polcommit.dta", gen(_polcommit)  // keep(match using)

*Only merging with one party per election from the parlgov dataset
g date_next = date
g gov_before_election = 1
merge m:1 country date_next pf_common_id gov_before_election using "parlgov.dta", gen(_parlgov)

*Year variable, issue dummies, and country dummies
g year = floor(date / 100)
encode issue, g(issue_num)
encode country, g(country_num)

*Included issues
keep if inlist(issue, "Agriculture") | inlist(issue, "Centralisation", "Constitutionalism", "Democracy", "EU", "Education", "Foreign policy", "Internationalism") | inlist(issue, "Labour groups", "Law and order", "Military", "Morality", "Multiculturalism", "National way of life", "Protectionism") | inlist(issue, "Welfare")

save "analysis.dta", replace
export delimited using "analysis.csv", replace


**# MAIN ANALYSIS
use "analysis.dta", replace

**# - Main effect
eststo model1_1: reg sh_i_char_commitment i.PositionChangeType1 i.cabinet_party LSaliency rile_index i.issue_num i.pf_common_id
g esample = 1 if e(sample)==1
tab country_num if esample==1
estadd scalar n_countries = r(r)

save "after analysis.dta", replace

*Figure 4
margins, at(PositionChangeType1=(0 1 2))
marginsplot, scheme(s1mono) xtitle(" ""Type of change") ///
    xlabel(0 `""No""change""' 1 `""Ideological""crystallization""' 2 `""Ideological""dilution""', labsize(small)) ///
    ytitle("Predicted share of election promises"" ") title("") note(" """, size(vsmall)) ///
    xscale(range(-0.5 2.5)) recast(scatter) ///
    ylabel(4 "4.0 %" 5 "5.0 %" 6 "6.0%" 7 "7.0%" 8 "8.0%" 9 "9.0%" 10 "10.0%" 11 "11.0%", angle(360) grid labsize(small)) ///
    ymtick(3.5(0.5)11.5, grid) aspectratio(1.1)
	
graph export "Figure 4.svg", replace

*Table 5
esttab model1_1  using "Table 5.rtf", replace label se stats(N r2 n_countries, labels(Observations R-squared "Number of countries")) nonotes wide star(* 0.05 ** 0.01 *** 0.001) addnotes("Notes: *p<.05, **p<.01, ***p<.001. Coefficients are unstandardized and estimated based on a pooled OLS-regression model with issue and party dummies included (not shown). Standard errors are in parentheses. Main independent variable is type of change (ideological dilution is when a party becomes ideologically more mixed on an issue from one election to the next, ideological crystallization is when a party becomes ideologically clearer on an issue, and no change is when a party is ideologically consistent across elections within a certain threshold).") varwidth(30)  cells(b(star fmt(a2)) se(par fmt(a2))) mtitles("" "" "" "") collabels("" "" "" "") title("Table 5: The effect of positional change on share of election promises within issues")   ///
	order(0.PositionChangeType1 1.PositionChangeType1 2.PositionChangeType1) ///
	refcat(13.country "Country" 0.cabinet_party "Government status" 0.PositionChangeType1 "Type of change", nolabel) ///
	varlabels(rile_index "Ideology (RILE)" 1.cabinet_party "Government party (ref = opposition party)" LSaliency "Saliency (lagged)" 0.PositionChangeType1 "- No change" 1.PositionChangeType1 "- Ideological crystallization" 2.PositionChangeType1 "- Ideological dilution" rile_index "Ideology (RILE)" _cons "Constant") ///
	drop(*issue_num *pf_common_id 0.cabinet_party) //  

**# - Interaction with saliency
use "after analysis.dta", replace

eststo model1_2a: reg sh_i_char_commitment i.PositionChangeType1Simple##c.LSaliency rile_index i.cabinet_party i.issue_num i.pf_common_id
tab country_num if e(sample)==1
estadd scalar n_countries = r(r)
testparm i.PositionChangeType1Simple#c.LSaliency

*Figure 5
su LSaliency, detail
local min = `r(p25)'
local min1 = `r(p25)' -0.05
local med = `r(p50)'
local max = `r(p75)'
local max1 = `r(p75)' + 0.05
local val1 = `min' + (`med' - `min')/3
local val2 = `min' + 2*(`med' - `min')/3
local val3 = `med' + (`max' - `med')/3
local val4 = `med' + 2*(`max' - `med')/3

margins, dydx(PositionChangeType1Simple) at(LSaliency = (`min' `val1' `val2' `med' `val3' `val4' `max'))
marginsplot, recastci(rarea) ciopts(color(gs8%40)) ///
    plotopts(lcolor(black) msymbol(none)) ///
    title(" ") yline(0, lcolor(black)) ///
    ytitle("The marginal effects of ideological dilution on the share of promises", size(small)) ///
    xlabel(`min' `""Low saliency" "(first quartile)""' `val1' `" "' `val2' `" "' `med' `""Median saliency""(second quartile)""' `val3' `" "' `val4' `" "' `max' `""High saliency""(third quartile)""', labsize(small)) ///
    xtitle(" ") ylabel(, labsize(small)) xscale(range(`min1' `max1')) ///
	ylabel(0(1)4, labsize(small)) ytick(0(0.2)4, grid) aspectratio(0.9)
graph export "Figure 5.svg", replace

*Table D1
esttab model1_2a using "Table D1.rtf",  /// 
 replace label se stats(N r2 n_countries, labels(Observations R-squared "Number of countries")) nonotes wide star(* 0.05 ** 0.01 *** 0.001) addnotes("Notes: *p<.05, **p<.01, ***p<.001. Coefficients are unstandardized and estimated based on a pooled OLS-regression model with issue and party dummies included (not shown). Standard errors are in parentheses. Interaction term consist of two variables: Issue saliency (measured at previous available election) and type of change (ideological dilution is when a party becomes ideologically more mixed on an issue from one election to the next, ideological crystallization is when a party becomes ideologically clearer on an issue, and no change is when a party is ideologically consistent across elections within a certain threshold).") varwidth(30)  cells(b(star fmt(a2)) se(par fmt(a2))) mtitles("" "" "" "") collabels("" "" "" "") title("Table D1: The effect of positional dilution on share of election promises moderated by the saliency of the issue")   ///
	order(1.PositionChangeType1Simple#c.LSaliency 0.PositionChangeType1Simple 1.PositionChangeType1Simple LSaliency ) ///
	refcat(13.country "Country" 0.cabinet_party "Government status" 0.PositionChangeType1Simple "Type of change" , nolabel) ///
	varlabels(rile_index "Ideology (RILE)"  1.cabinet_party "Government party (ref = opposition party)" LSaliency "Saliency (lagged)" 1.PositionChangeType1Simple#c.LSaliency "Ideological dilution (ref = no change/ideological crystallization) X Saliency (lagged)" 1.PositionChangeType1Simple "Ideological dilution (ref = No change/ideological crystallization)"  _cons "Constant") ///
	drop(*issue_num *pf_common_id 0.cabinet_party 0.PositionChangeType1Simple 0.PositionChangeType1Simple#c.LSaliency ) 

**# ROBUSTNESS TESTS
**# - Ideological clarity (mean across issues)
use "after analysis.dta", replace

eststo model1: reg sh_i_char_commitment i.PositionChangeType1Simple##c.meanPositionAbs i.cabinet_party LSaliency i.issue_num i.pf_common_id
tab country_num if e(sample)==1
estadd scalar n_countries = r(r)

*Table D2
esttab model1 using "Table D2.rtf", replace label se stats(N r2 n_countries, labels(Observations R-squared "Number of countries")) nonotes wide star(* 0.05 ** 0.01 *** 0.001) addnotes("Notes: *p<.05, **p<.01, ***p<.001. Coefficients are unstandardized and estimated based on a pooled OLS-regression model with issue and party dummies included (not shown). Standard errors are in parentheses. Interaction term consists of two variables: Ideological clarity (based on the party's average degree of ideological clarity across issues) and ideological dilution (which occurs when a party becomes ideologically more mixed on an issue from one election to the next, and which is in contrast to both ideological crystallization that occurs when a party becomes ideologically clearer on an issue and no change, which occurs when a party is ideologically consistent across elections within a certain threshold).") varwidth(30)  cells(b(star fmt(a2)) se(par fmt(a2))) mtitles("" "" "" "") collabels("" "" "" "") title("Table D2: The effect of ideological dilution on the share of election promises moderated by the average degree of ideological clarity across issues")   ///
	order(1.PositionChangeType1Simple#c.meanPositionAbs 1.PositionChangeType1Simple meanPositionAbs) ///
	refcat(13.country "Country" 0.cabinet_party "Government status" , nolabel) ///
	varlabels(1.cabinet_party "Government party (ref = opposition party)" 1.PositionChangeType1Simple#c.meanPositionAbs "Ideological dilution (ref = no change/ideological crystallization) X Ideological clarity (mean across issues)" meanPositionAbs "Ideological clarity (mean across issues)" 1.PositionChangeType1Simple "Ideological dilution (ref = No change/ideological crystallization)" LSaliency "Saliency (lagged)"  _cons "Constant") ///
	drop(*issue_num *pf_common_id 0.cabinet_party 0.PositionChangeType1Simple 0.PositionChangeType1Simple#c.meanPositionAbs ) // 


*Figure D2
su meanPositionAbs if e(sample)==1, detail
local min = `r(p25)'
local min1 = `r(p25)' -0.05
local med = `r(p50)'
local max = `r(p75)'
local max1 = `r(p75)' + 0.05
local val1 = `min' + (`med' - `min')/3
local val2 = `min' + 2*(`med' - `min')/3
local val3 = `med' + (`max' - `med')/3
local val4 = `med' + 2*(`max' - `med')/3

margins, dydx(PositionChangeType1Simple) at(meanPositionAbs = (`min' `val1' `val2' `med' `val3' `val4' `max'))
marginsplot, recastci(rarea) ciopts(color(gs8%40)) ///
    plotopts(lcolor(black) msymbol(none)) ///
    title(" ") yline(0, lcolor(black)) ///
    ytitle("The marginal effects of ideological dilution on the share of promises", size(small)) ///
    xlabel(`min' `""Low clarity" "(first quartile)""' `val1' `" "' `val2' `" "' `med' `""Median clarity""(second quartile)""' `val3' `" "' `val4' `" "' `max' `""High clarity""(third quartile)""', labsize(small)) ///
    xtitle(" ") ylabel(, labsize(small)) xscale(range(`min1' `max1')) ///
	ylabel(-1(1)4, labsize(small)) ytick(-1(0.2)4, grid) aspectratio(0.9)
graph export "Figure D2.svg", replace

**# - Centre parties
use "after analysis.dta", replace

eststo model1: reg sh_i_char_commitment i.PositionChangeType1Simple##c.rile_index_abs i.cabinet_party LSaliency i.issue_num i.pf_common_id
tab country_num if e(sample)==1
estadd scalar n_countries = r(r)

*Table D3
esttab model1 using "Table D3.rtf", replace label se stats(N r2 n_countries, labels(Observations R-squared "Number of countries")) nonotes wide star(* 0.05 ** 0.01 *** 0.001) addnotes("Notes: *p<.05, **p<.01, ***p<.001. Coefficients are unstandardized and estimated based on a pooled OLS-regression model with issue and party dummies included (not shown). Standard errors are in parentheses. Interaction term consists of two variables: Party centrism (based on the absolute distance from a party's position on the Comparative Manifesto Project's right/left-indicator  - RILE - to 0) and ideological dilution (which occurs when a party becomes ideologically more mixed on an issue from one election to the next, and which is in contrast to both ideological crystallization that occurs when a party becomes ideologically clearer on an issue and to no change which occurs when a party is ideologically consistent across elections within a certain threshold).") varwidth(30)  cells(b(star fmt(a2)) se(par fmt(a2))) mtitles("" "" "" "") collabels("" "" "" "") title("Table D3: The effect of ideological dilution on the share of election promises moderated by the extremity of the party")   ///
	order(1.PositionChangeType1Simple#c.rile_index_abs 1.PositionChangeType1Simple rile_index_abs) ///
	refcat(13.country "Country" 0.cabinet_party "Government status" , nolabel) ///
	varlabels(1.cabinet_party "Government party (ref = opposition party)" 1.PositionChangeType1Simple#c.rile_index_abs "Ideological dilution (ref = no change/ideological crystallization) X RILE extremity" rile_index_abs "RILE extremity" 1.PositionChangeType1Simple "Ideological dilution (ref = No change/ideological crystallization)" LSaliency "Saliency (lagged)"  _cons "Constant") ///
	drop(*issue_num *pf_common_id 0.cabinet_party 0.PositionChangeType1Simple 0.PositionChangeType1Simple#c.rile_index_abs )  

**# - Different operationalizations of independent variable
use "after analysis.dta", replace

eststo model1: reg sh_i_char_commitment i.PositionChangeType05 i.cabinet_party rile_index LSaliency i.issue_num i.pf_common_id
tab country_num if e(sample)==1
estadd scalar n_countries = r(r)

*Table D4
esttab model1  using "Table D4.rtf", replace label se stats(N r2 n_countries, labels(Observations R-squared "Number of countries")) nonotes wide star(* 0.05 ** 0.01 *** 0.001) addnotes("Notes: *p<.05, **p<.01, ***p<.001. Coefficients are unstandardized and estimated based on a pooled OLS-regression model with issue and party dummies included (not shown). Standard errors are in parentheses. Main independent variable is type of change (ideological dilution is when a party becomes ideologically more mixed on an issue from one election to the next, ideological crystallization is when a party becomes ideologically clearer on an issue, and no change is when a party is ideologically consistent across elections within a certain threshold).") varwidth(30)  cells(b(star fmt(a2)) se(par fmt(a2))) mtitles("" "" "" "") collabels("" "" "" "") title("Table D4: The effect of positional change on share of election promises within issues (no change threshold = 0.5)")   ///
	order(0.PositionChangeType05 1.PositionChangeType05 2.PositionChangeType05) ///
	refcat(13.country "Country" 0.cabinet_party "Government status" 0.PositionChangeType05 "Type of change", nolabel) ///
	varlabels(rile_index "Ideology (RILE)" 1.cabinet_party "Government party (ref = opposition party)" LSaliency "Saliency (lagged)" 0.PositionChangeType05 "- No change" 1.PositionChangeType05 "- Ideological crystallization" 2.PositionChangeType05 "- Ideological dilution" _cons "Constant") ///
	drop(*issue_num *pf_common_id 0.cabinet_party) //  
	
eststo model1: reg sh_i_char_commitment i.PositionChangeType2 i.cabinet_party rile_index LSaliency i.issue_num i.pf_common_id 
tab country_num if e(sample)==1
estadd scalar n_countries = r(r)

*Table D5
esttab model1  using "Table D5.rtf", replace label se stats(N r2 n_countries, labels(Observations R-squared "Number of countries")) nonotes wide star(* 0.05 ** 0.01 *** 0.001) addnotes("Notes: *p<.05, **p<.01, ***p<.001. Coefficients are unstandardized and estimated based on a pooled OLS-regression model with issue and party dummies included (not shown). Standard errors are in parentheses. Main independent variable is type of change (ideological dilution is when a party becomes ideologically more mixed on an issue from one election to the next, ideological crystallization is when a party becomes ideologically clearer on an issue, and no change is when a party is ideologically consistent across elections within a certain threshold).") varwidth(30)  cells(b(star fmt(a2)) se(par fmt(a2))) mtitles("" "" "" "") collabels("" "" "" "") title("Table D5: The effect of positional change on share of election promises within issues (no change threshold = 2)")   ///
	order(0.PositionChangeType2 1.PositionChangeType2 2.PositionChangeType2) ///
	refcat(13.country "Country" 0.cabinet_party "Government status" 0.PositionChangeType2 "Type of change", nolabel) ///
	varlabels(rile_index "Ideology (RILE)"  1.cabinet_party "Government party (ref = opposition party)" LSaliency "Saliency (lagged)" 0.PositionChangeType2 "- No change" 1.PositionChangeType2 "- Ideological crystallization" 2.PositionChangeType2 "- Ideological dilution" _cons "Constant") ///
	drop(*issue_num *pf_common_id 0.cabinet_party) //  
	

eststo model1: reg sh_i_char_commitment i.PositionChangeType3 i.cabinet_party rile_index LSaliency i.issue_num i.pf_common_id //
tab country_num if e(sample)==1
estadd scalar n_countries = r(r)

*Table D6
esttab model1  using "Table D6.rtf", replace label se stats(N r2 n_countries, labels(Observations R-squared "Number of countries")) nonotes wide star(* 0.05 ** 0.01 *** 0.001) addnotes("Notes: *p<.05, **p<.01, ***p<.001. Coefficients are unstandardized and estimated based on a pooled OLS-regression model with issue and party dummies included (not shown). Standard errors are in parentheses. Main independent variable is type of change (ideological dilution is when a party becomes ideologically more mixed on an issue from one election to the next, ideological crystallization is when a party becomes ideologically clearer on an issue, and no change is when a party is ideologically consistent across elections within a certain threshold).") varwidth(30)  cells(b(star fmt(a2)) se(par fmt(a2))) mtitles("" "" "" "") collabels("" "" "" "") title("Table D6: The effect of positional change on share of election promises within issues (no change threshold = 3)")   ///
	order(0.PositionChangeType3 1.PositionChangeType3 2.PositionChangeType3) ///
	refcat(13.country "Country" 0.cabinet_party "Government status" 0.PositionChangeType3 "Type of change", nolabel) ///
	varlabels(rile_index "Ideology (RILE)"  1.cabinet_party "Government party (ref = opposition party)" LSaliency "Saliency (lagged)" 0.PositionChangeType3 "- No change" 1.PositionChangeType3 "- Ideological crystallization" 2.PositionChangeType3 "- Ideological dilution" _cons "Constant") ///
	drop(*issue_num *pf_common_id 0.cabinet_party) //  


eststo model1: reg sh_i_char_commitment PositionChangeCen i.cabinet_party rile_index LSaliency i.issue_num i.pf_common_id 
tab country_num if e(sample)==1
estadd scalar n_countries = r(r)

*Table D7
esttab model1 using "Table D7.rtf", replace label se stats(N r2 n_countries, labels(Observations R-squared "Number of countries")) nonotes wide star(* 0.05 ** 0.01 *** 0.001) addnotes("Notes: *p<.05, **p<.01, ***p<.001. Coefficients are unstandardized and estimated based on a pooled OLS-regression model with issue and party dummies included (not shown). Standard errors are in parentheses. Main independent variable is degree of change (negative values mean that the party became more ideologically clear on an issue from one election to the next, positive values mean that the party became more mixed, while 0 means that the party did not change).") varwidth(30)  cells(b(star fmt(a2)) se(par fmt(a2))) mtitles("" "" "" "") collabels("" "" "" "") title("Table D7: The effect of positional change on share of election promises within issues")   ///
	order() ///
	refcat(13.country "Country" 0.cabinet_party "Government status", nolabel) ///
	varlabels(PositionChangeCen "Degree of change" rile_index "Ideology (RILE)" 1.cabinet_party "Government party (ref = opposition party)" LSaliency "Saliency (lagged)" rile_index "Ideology (RILE)" _cons "Constant") ///
	drop(*issue_num *pf_common_id 0.cabinet_party) //  


eststo model1: reg sh_i_char_commitment PositionChangeCenZero i.cabinet_party rile_index LSaliency i.issue_num i.pf_common_id
tab country_num if e(sample)==1
estadd scalar n_countries = r(r)

*Table D8
esttab model1 using "Table D8.rtf", replace label se stats(N r2 n_countries, labels(Observations R-squared "Number of countries")) nonotes wide star(* 0.05 ** 0.01 *** 0.001) addnotes("Notes: *p<.05, **p<.01, ***p<.001. Coefficients are unstandardized and estimated based on a pooled OLS-regression model with issue and party dummies included (not shown). Standard errors are in parentheses. Main independent variable is degree of dilution (positive values mean that the party became more ideologically mixed on an issue from one election to the next, while 0 means that the party did not change or became more ideologically clear).") varwidth(30)  cells(b(star fmt(a2)) se(par fmt(a2))) mtitles("" "" "" "") collabels("" "" "" "") title("Table D8: The effect of positional change on share of election promises within issues")   ///
	order() ///
	refcat(13.country "Country" 0.cabinet_party "Government status", nolabel) ///
	varlabels(PositionChangeCenZero "Degree of dilution" rile_index "Ideology (RILE)" 1.cabinet_party "Government party (ref = opposition party)" LSaliency "Saliency (lagged)" rile_index "Ideology (RILE)" _cons "Constant") ///
	drop(*issue_num *pf_common_id 0.cabinet_party) //  

	
**# - Extra control variables 
use "after analysis.dta", replace

eststo model1: reg sh_i_char_commitment i.PositionChangeType1 i.cabinet_party LSaliency rile_index vote_share i.mainstream parl_experience i.issue_num i.pf_common_id
tab country_num if e(sample)==1
estadd scalar n_countries = r(r)

*Table D9
esttab model1 using "Table D9.rtf", replace label se stats(N r2 n_countries, labels(Observations R-squared "Number of countries")) nonotes wide star(* 0.05 ** 0.01 *** 0.001) addnotes("Notes: *p<.05, **p<.01, ***p<.001. Coefficients are unstandardized and estimated based on a pooled OLS-regression model with issue and party dummies included (not shown). Standard errors are in parentheses. Main independent variable is type of change (ideological dilution is when a party becomes ideologically more mixed on an issue from one election to the next, ideological crystallization is when a party becomes ideologically clearer on an issue, and no change is when a party is ideologically consistent across elections within a certain threshold).") varwidth(30)  cells(b(star fmt(a2)) se(par fmt(a2))) mtitles("" "" "" "") collabels("" "" "" "") title("Table D9: The effect of positional change on share of election promises within issues")   ///
	order(0.PositionChangeType1 1.PositionChangeType1 2.PositionChangeType1) ///
	refcat(13.country "Country" 0.cabinet_party "Government status" 0.PositionChangeType1 "Type of change", nolabel) ///
	varlabels(rile_index "Ideology (RILE)" 1.cabinet_party "Government party (ref = opposition party)" vote_share "Vote share" 1.mainstream "Mainstream party (ref = niche)" LSaliency "Saliency (lagged)" PositionAbs "Positional extremity" 0.PositionChangeType1 "- No change" 1.PositionChangeType1 "- Ideological crystallization" 2.PositionChangeType1 "- Ideological dilution" parl_experience "Parliamentary experience" _cons "Constant") ///
	drop(*issue_num *pf_common_id 0.cabinet_party 0.mainstream) //  
	
**# - Country/year fixed effects
use "after analysis.dta", replace

eststo model1: reg sh_i_char_commitment i.PositionChangeType1  i.cabinet_party LSaliency rile_index i.issue_num i.country_num i.year
tab country_num if e(sample)==1
estadd scalar n_countries = r(r)

*Table D10
esttab model1  using "Table D10.rtf", replace label se stats(N r2 n_countries, labels(Observations R-squared "Number of countries")) nonotes wide star(* 0.05 ** 0.01 *** 0.001) addnotes("Notes: *p<.05, **p<.01, ***p<.001. Coefficients are unstandardized and estimated based on a pooled OLS-regression model with issue, country, and year dummies included (not shown). Standard errors are in parentheses. Main independent variable is type of change (ideological dilution is when a party becomes ideologically more mixed on an issue from one election to the next, ideological crystallization is when a party becomes ideologically clearer on an issue, and no change is when a party is ideologically consistent across elections within a certain threshold).") varwidth(30)  cells(b(star fmt(a2)) se(par fmt(a2))) mtitles("" "" "" "") collabels("" "" "" "") title("Table D10: The effect of positional change on share of election promises within issues")   ///
	order(0.PositionChangeType1 1.PositionChangeType1 2.PositionChangeType1) ///
	refcat(13.country "Country" 0.cabinet_party "Government status" 0.PositionChangeType1 "Type of change", nolabel) ///
	varlabels(rile_index "Ideology (RILE)" 1.cabinet_party "Government party (ref = opposition party)" LSaliency "Saliency (lagged)" 0.PositionChangeType1 "- No change" 1.PositionChangeType1 "- Ideological crystallization" 2.PositionChangeType1 "- Ideological dilution"  _cons "Constant") ///
	drop(*issue_num *country_num *year 0.cabinet_party) //  
	

**# Negative Binominal Regression
use "after analysis.dta", replace

eststo model1: nbreg sh_i_char_commitment i.PositionChangeType1  i.cabinet_party LSaliency rile_index i.issue_num i.pf_common_id
tab country_num if e(sample)==1
estadd scalar n_countries = r(r)

*Table D11
esttab model1 using "Table D11.rtf", replace  label se stats(N r2_p n_countries, labels(Observations "Pseudo-R-squared" "Number of countries")) nonotes wide star(* 0.05 ** 0.01 *** 0.001) addnotes("Notes: *p<.05, **p<.01, ***p<.001. Coefficients are unstandardized and estimated based on a negative binomial regression model with issue and party dummies included (not shown). Standard errors are in parentheses. Main independent variable is type of change (ideological dilution is when a party becomes ideologically more mixed on an issue from one election to the next, ideological crystallization is when a party becomes ideologically clearer on an issue, and no change is when a party is ideologically consistent across elections within a certain threshold).") varwidth(30)  cells(b(star fmt(a2)) se(par fmt(a2))) mtitles("" "" "" "") collabels("" "" "" "") title("Table D11: The effect of positional change on share of election promises within issues")   ///
	order(0.PositionChangeType1 1.PositionChangeType1 2.PositionChangeType1) ///
	refcat(13.country "Country" 0.cabinet_party "Government status" 0.PositionChangeType1 "Type of change", nolabel) ///
	varlabels(rile_index "Ideology (RILE)" 1.cabinet_party "Government party (ref = opposition party)" LSaliency "Saliency (lagged)" 0.PositionChangeType1 "- No change" 1.PositionChangeType1 "- Ideological crystallization" 2.PositionChangeType1 "- Ideological dilution"  _cons "Constant") ///
	drop(*issue_num *pf_common_id 0.cabinet_party lnalpha) //  
	
	
**# Hold one out analysis
use "after analysis.dta", replace

levelsof country_num if esample==1, local(cn)
local a ""

foreach c of local cn {
	eststo model1_7_`c': reg sh_i_char_commitment i.PositionChangeType1Simple i.cabinet_party LSaliency rile_index i.issue_num i.pf_common_id if country_num!=`c'
    local name : label country_num `c'
	local a "`a' `name'"
}

*Figure D3
coefplot model1_7_*, keep(1.PositionChangeType1Simple) ///
    xline(0, lcolor(black)) xtitle(" "" " " " " ""The effect of ideological dilution on the share of election promises""(relative to no change or to ideological crystallization)") ///
    ytitle(" ") xscale(range(0 4)) ylabel(1 " ", notick) xlabel(0 (1) 4) legend(label(2 "Excluding Australia") label(4 "Excluding Austria") label(6 "Excluding Belgium") label(8 "Excluding Bulgaria") label(10 "Excluding Canada") label(12 "Excluding Croatia") label(14 "Excluding Czech Republic") label(16 "Excluding Denmark") label(18 "Excluding Estonia") label(20 "Excluding Finland") label(22 "Excluding France") label(24 "Excluding Germany") label(26 "Excluding Greece") label(28 "Excluding Hungary") label(30 "Excluding Iceland") label(32 "Excluding Ireland") label(34 "Excluding Latvia") label(36 "Excluding Lithuania") label(38 "Excluding Luxembourg") label(40 "Excluding Netherlands") label(42 "Excluding New Zealand") label(44 "Excluding Norway") label(46 "Excluding Poland") label(48 "Excluding Portugal") label(50 "Excluding Romania") label(52 "Excluding Slovakia") label(54 "Excluding Slovenia") label(56 "Excluding Spain") label(58 "Excluding Sweden") label(60 "Excluding Switzerland") label(62 "Excluding United Kingdom") label(64 "Excluding United States") size(small))
	graph export "Figure D3.svg", replace

**# DESCRIPTIVES
use "after analysis.dta", replace

**# - Dependent variable 
su sh_i_char_commitment if esample==1

**# - Ideological clarity (mean across issues)
su PositionAbs

hist meanPositionAbs if esample==1, percent ytitle(" ") ylabel(0 "0 %" 1 "1 %" 2 "2 %" 3 "3 %" 4 "4 %" 5 "5 %" 6 "6 %" 7 "7 %" 8 "8 %") xtitle("Ideological clarity""(mean across issues)") xscale(range(0 8)) xlabel(0(1) 8)
graph export "Figure D1.svg", replace

**# - Number of sentences coded, number of election programmes, included issues, and included manifestos
import delimited "polcommit_v2.0.csv", clear encoding(UTF-8) // 
egen manifesto = tag(countryname party date)
tab manifesto if manifesto==1
egen party_num = tag(countryname party)
tab party_num if party_num==1


use "after analysis.dta", replace

egen totalsentences = total(i_sentences) if esample==1
egen electionprogram = tag(country_num dataset_party_id date) if esample==1
tab electionprogram if esample==1  // Number of election manifestoes
codebook totalsentences if esample==1  // Number of quasi-sentences
codebook dataset_party_id if esample==1 // Number of parties
codebook country_num if esample==1 

bysort electionprogram country (date partyname): g num1 = _n
bysort electionprogram country date (partyname): g num2 = _n
sort electionprogram country date partyname
g country2 = country
replace country = "" if num1!=1
tostring date, replace
gen date3 = substr(date, 1, 4) + "-" + substr(date, 5, 2)
replace date = "" if num2!=1
browse country partyname date num1 num2  if electionprogram==1
keep if electionprogram==1
rename (country date partyname) (Country Election Party)
order Country Election Party
keep Country Election Party

export excel using "manifestoes included.xlsx", replace firstrow(variables)